package com.wzh.project.utils.ssh2;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.wzh.project.config.ssh2.Ssh2Config;
import com.wzh.project.utils.PrimaryUUID;
import com.wzh.project.utils.string.StringUtils;

import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.SCPClient;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;

/**
 * @author : 汪振海
 * @createdDate : Jan 2, 2020 10:21:44 AM
 * @description : 通过远程连接到服务器，执行命令<br>
 *              可支持：1执行正常
 *
 */
public class Ssh2Utils {

	private static final Logger logger = LogManager.getLogger(Ssh2Utils.class);
	
	private static String DEFAULTCHARTSET = "UTF-8";

	private static Ssh2Utils ssh2 = null;
	
	private Connection connection=null;
	
	
	
	private Ssh2Utils(String host,String userName,String password) {
		//为了方便每次都重新创建
		connection=login(host, userName, password);
	}


	
	public static Ssh2Utils getInit(String host,String userName,String password) {
		if (StringUtils.isEmpty(host,userName,password)) {
			//使用默认的
			Ssh2Config ssh2Config=new Ssh2Config();
			ssh2=new Ssh2Utils(ssh2Config.getHost(), ssh2Config.getUserName(), ssh2Config.getPassword());
		}else {
			ssh2=new Ssh2Utils(host, userName, password);
		}
		return ssh2;
	}
	/**
	 * 登录主机
	 * 
	 * @return 登录成功返回true，否则返回false
	 */
	private Connection login(String ip, String userName, String userPwd) {
		boolean flg = false;
		Connection conn = null;
		try {
			conn = new Connection(ip);//默认使用22端口进行连接
			conn.connect();// 连接
			flg = conn.authenticateWithPassword(userName, userPwd);// 认证
			if (flg) {
				logger.info("=========登录成功=========" + conn);
				return conn;
			}
		} catch (IOException e) {
			logger.error("=========登录失败=========" + e.getMessage());
			e.printStackTrace();
		}
		return conn;
	}
	
	public boolean exit() {
		try {
			connection.close();
		} catch (Exception e) {
			// TODO: handle exception
		}finally {
			return true;
		}
	}

	/**
	 * 多个命令可以直接使用 \r\n 进行分割
	 * 或者使用&&进行分割
	 * @param command
	 * @return
	 * @throws Exception
	 */
	public String runCommond(String command) throws Exception {
		Session session=null;
		String result=null;
		try {
			session = connection.openSession();
			logger.debug("执行的命令为:"+command);
			session.execCommand(command);
			result = processStdout(session.getStdout(), DEFAULTCHARTSET);
		} catch (Exception e) {
			logger.error("执行命令失败，失败原因为"+e);
		}finally {
			session.close();
//			connection.close();
		}
		return result;
	}
	
	public void runCommondNoResult(String command) throws Exception {
		Session session=null;
		try {
			session = connection.openSession();
			logger.debug("执行的命令为:"+command);
			session.execCommand(command);
//			result = processStdout(session.getStdout(), DEFAULTCHARTSET);
		} catch (Exception e) {
			logger.error("执行命令失败，失败原因为"+e);
		}finally {
//			session.close();
//			connection.close();
		}
	}
	
	/**
	 * 返回命令执行后的结果
	 * @param in
	 * @param charset
	 * @return
	 */
    public static String processStdout(InputStream in, String charset){
		InputStream stdout = new StreamGobbler(in);
		StringBuffer buffer = new StringBuffer();
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(stdout, charset));
			String line = null;
			while ((line = br.readLine()) != null) {
				buffer.append(line + "\n");
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return buffer.toString();
    }
	
    /**
     * 从远程获取文件，放在本地
     * @param remoteFile		远程文件路径
     * @param path				本地文件路径
     * @return
     */
	public boolean getFile(String remoteFile, String path) {
		try {
			String newRemoteFile=beforeGetFile(remoteFile);
			SCPClient scpClient = connection.createSCPClient();
			scpClient.get(newRemoteFile, path);
//			afterGetFile(remoteFile, newRemoteFile, path);
			return true;
		} catch (Exception e) {
			logger.debug("操作失败!"+e);
		} finally {
			connection.close();
		}
		return false;
	}
	
	/**
	 * 在scp拉取文件之前进行的操作
	 * @param remoteFile
	 * @throws Exception 
	 */
	private String beforeGetFile(String remoteFile) throws Exception {
		if (StringUtils.isEmpty(remoteFile)) {
			throw new Exception("远程文件名为空");
		}
		if (remoteFile.contains(".")) {
			//说明传输的是一个文件，正常操作
			return remoteFile;
		}else {
			//说明是一个文件夹，需要进行预处理
			if (!remoteFile.endsWith("/")) {
				remoteFile=remoteFile+"/";
			}
			String fileName=remoteFile+PrimaryUUID.getUUID()+".tar.gz";
			String cmd="tar -zcvf "+fileName+" "+remoteFile;
			runCommond(cmd);
			return fileName;
		}
	}
	
	/**
	 * 在scp拉取文件之后进行的操作，主要用于解压
	 * @param remoteFile
	 * @param newRemoteFile
	 * @param path
	 * @return
	 * @throws Exception
	 */
	private void afterGetFile(String remoteFile,String newRemoteFile,String path) throws Exception {
		if (StringUtils.isEmpty(remoteFile,newRemoteFile,path)) {
			throw new Exception("远程文件名为空");
		}
		if (remoteFile.equals(newRemoteFile)) {
			//说明传输的是一个文件，正常操作
			return ;
		}else {
			//说明是一个文件夹，需要进行转移之后预处理
			newRemoteFile=newRemoteFile.substring(newRemoteFile.lastIndexOf("/")+1);
			String cmd="cd "+path+"tar -zxvf "+newRemoteFile+" -C "+path;
			runCommond(cmd);
		}
		File file=new File(path+"/"+newRemoteFile);
		file.delete();
	}

	/**
	 * 向远程发送文件  			
	 * @param localFile					本地文件
	 * @param remoteTargetDirectory		远程文件
	 * @return
	 */
	public boolean putFile(String localFile, String remoteTargetDirectory) {
		try {
			SCPClient scpClient = connection.createSCPClient();
			scpClient.put(localFile, remoteTargetDirectory);
			logger.debug("认证成功!");
			return true;
		} catch (Exception ex) {
			logger.debug("认证失败!");
			ex.printStackTrace();
		} finally {
			connection.close();
		}
		return false;
	}
	
	
	
	public static void main(String[] args) throws Exception {
		String cmd1="pwd \r\n cd /home/k8s_data/istio/networking \r\n pwd";
		String cmd2="pwd && cd /home/k8s_data/istio/networking && pwd";
//		String cmd3="scp -r /home/k8s_data root@10.23.11.131:/etc/squid &&css123456";
		String result=Ssh2Utils.getInit(null, null, null).runCommond(cmd1);
		result=Ssh2Utils.getInit(null, null, null).runCommond(cmd2);
		result=Ssh2Utils.getInit(null, null, null).runCommond(cmd1);
		logger.debug("执行之后的结果为:"+result);
		
//		logger.debug("开始获取远程文件");
//		String remoteFile="/home/k8s_data/istio"; //文件名字
//		String path="D:\\";
//		String localFile="D:\\loosejar-1.1.0.jar";
//		String remoteTargetDirectory="/home/k8s_data";
//		boolean scpResult=Ssh2Utils.getInit(null, null, null).getFile(remoteFile, path);
//		logger.debug(scpResult);
//		
//		logger.debug("开始向远程传递文件");
//		scpResult=Ssh2Utils.getInit(null, null, null).putFile(localFile, remoteTargetDirectory);
//		logger.debug(scpResult);
	}
	
	
	
}
